package clientSide.javaGui;

import static serverSide.Server.*;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import org.json.simple.*;

import serverSide.GameController;

import clientSide.*;

public class ProfilePage extends JFrame {
	Image bg;
	Player player;
	
	GameWaiting gw;
	
	public ProfilePage(Rectangle r, Image img, Socket socket, ObjectOutputStream oos, ObjectInputStream ois, String username) {
		this.bg = img;
		this.player = new Player(socket, oos, ois, username);

		this.setTitle("Iran Game Center");
		this.setContentPane(new JComponent() {
			@Override
			protected void paintComponent(Graphics g) {
				g.drawImage(bg,0,0,getParent().getWidth()+15,getParent().getHeight(),
						0,0,getParent().getWidth(),getParent().getHeight(),null);
				super.paintComponent(g);
			}
		});
		
		JButton tmpButton = new JButton("PlayGame");
		tmpButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				int sel = JOptionPane.showOptionDialog(null, "Choose a game!", "Warning",
						JOptionPane.DEFAULT_OPTION,JOptionPane.WARNING_MESSAGE, null,
						GameController.games, GameController.games[0]);
				if(sel != JOptionPane.CLOSED_OPTION)
					gameConnection(gameRequest(sel));
			}
		});
		tmpButton.setBounds(10, 10, 150, 25);
		this.add(tmpButton);
		
		this.setResizable(false);
		this.setBounds(r);
		this.setVisible(true);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
	
	private boolean gameConnection(JSONObject msg) {
		try {
			player.getObjectOutputStream().writeObject(msg);
		} catch(Exception ex) {
			ex.printStackTrace();
			return false;
		}
		try {
			Object obj;
			if((obj = player.getObjectInputStream().readObject()) != null) {
				if(updateState((JSONObject)obj))
					return true;
				return false;
			}
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return false;
	}
	
	private boolean updateState(JSONObject msg) {
		switch ((int)msg.get(SUBJECT_KEY)) {
		case SUBJECT_VALUE_GAMEREQUEST:
			if((int)msg.get(SUBJECT_GAMEREQUEST_KEY_STATE) == SUBJECT_GAMEREQUEST_VALUE_GO)
				readyForGame(msg);
			else if((int)msg.get(SUBJECT_GAMEREQUEST_KEY_STATE) == SUBJECT_GAMEREQUEST_VALUE_WAIT)
				waitForGame();
			break;
		default:
			break;
		}
		return false;
	}
	
	public void readyForGame(JSONObject json) {
		System.out.println("rush to the game DuDe---->"+(String)json.get(SUBJECT_GAMEREQUEST_KEY_PLAYER1)+" vs "+
				(String)json.get(SUBJECT_GAMEREQUEST_KEY_PLAYER2));
		new GamePage(this.getBounds(), bg, player,json);
		this.dispose();
	}
	
	public void waitForGame() {
		System.out.println("u should wait bro");
		this.setEnabled(false);
		gw = new GameWaiting();
	}
	
	private JSONObject gameRequest(int choice) {
		JSONObject out = new JSONObject();
		out.put(SUBJECT_KEY, SUBJECT_VALUE_GAMEREQUEST);
		out.put(SUBJECT_GAMEREQUEST_KEY_USER, player.getName());
		switch (choice) {
		case 0:
			out.put(SUBJECT_GAMEREQUEST_KEY_TYPE, SUBJECT_GAMEREQUEST_VALUE_TICTACTOI);
			break;
		default:
			break;
		}
		
		return out;
	}
	
	private class GameWaiting extends JFrame {
		final JLabel l = new JLabel();
		Thread t1,t2;
		
		public GameWaiting() {
			t1 = new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						Object obj;
						if((obj = player.getObjectInputStream().readObject()) != null) {
							JSONObject json = (JSONObject)obj;
							if((int)json.get(SUBJECT_KEY) == SUBJECT_VALUE_GAMEREQUEST)
								if((int)json.get(SUBJECT_GAMEREQUEST_KEY_STATE) == SUBJECT_GAMEREQUEST_VALUE_GO) {
									dispose();
									readyForGame(json);
									return;
								}
						}
					} catch(Exception ex) {
						ex.printStackTrace();
					}
				}
			});
			t1.start();
			
			t2 = new Thread(new Runnable() {
				@Override
				public void run() {
					String str = "Waiting for another player.";
					for (int i = 0; i < 10; i++) {
						l.setText(str);
						str += ".";
						if(i==9) {
							str = "Waiting for another player.";
							i = 0;
						}
						try {
							Thread.sleep(500);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			});
			t2.start();
			
			this.add(l);
			
			this.setResizable(false);
			this.setBounds(400,400,300,100);
			this.setVisible(true);
			/**
			 * Fix defaultCloseOperation better 
			 */
			this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		}
	}
}
